﻿
using BoilenEditor.Primitives;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace BoilenEditor {

    public partial class SearchWindow : Window {

        private SearchData searchData_;
        private string selectedText_;


        public static readonly DependencyProperty ShowReplaceProperty = DependencyProperty.Register(
            "ShowReplace", typeof( bool ), typeof( SearchWindow ),
            new PropertyMetadata( false )
        );


        public SearchWindow( Window owner ) {
            InitializeComponent( );

            this.Owner = owner;
        }


        public SearchData SearchData {
            get { return this.searchData_; }
            private set {
                this.searchData_ = value;
                this.SearchDataChanged( this, EventArgs.Empty );
            }
        }

        public string SelectedText {
            get { return this.selectedText_; }
            set {
                this.selectedText_ = value;
                this.preview_.Text = value;
            }
        }

        public bool ShowReplace {
            get { return (bool)GetValue( ShowReplaceProperty ); }
            set { SetValue( ShowReplaceProperty, value ); }
        }

        public event EventHandler SearchDataChanged = delegate { };


        private bool IsCaseSensitive {
            get { return this.caseSensitive_.IsChecked.Value; }
        }

        private bool UseRegex {
            get { return this.useRegex_.IsChecked.Value; }
        }

        private bool Wrap {
            get { return !this.noWrap_.IsChecked.Value; }
        }


        private void FindNext( object sender, RoutedEventArgs e ) {
            UpdateSearchData( this.search_.Text, null, true, false );
        }

        private void FindPrevious( object sender, RoutedEventArgs e ) {
            UpdateSearchData( this.search_.Text, null, false, false );
        }

        private void Replace( object sender, RoutedEventArgs e ) {
            UpdateSearchData( this.search_.Text, this.replace_.Text, true, false );
        }

        private void ReplaceAll( object sender, RoutedEventArgs e ) {
            UpdateSearchData( this.search_.Text, this.replace_.Text, true, true );
        }

        private void TextBoxGotFocus( object sender, RoutedEventArgs e ) {
            TextBox textBox = (TextBox)sender;
            textBox.SelectAll( );
        }


        private void SearchCanExecute( object sender, CanExecuteRoutedEventArgs e ) {
            if( this.search_.Text.Length > 0 )
                e.CanExecute = true;
        }

        private void FindExecuted( object sender, ExecutedRoutedEventArgs e ) {
            this.ShowReplace = false;
        }

        private void ReplaceExecuted( object sender, ExecutedRoutedEventArgs e ) {
            this.ShowReplace = true;
        }

        private void CloseExecuted( object sender, ExecutedRoutedEventArgs e ) {
            this.Hide( );
        }

        protected override void OnClosing( CancelEventArgs e ) {
            base.OnClosing( e );

            e.Cancel = true;
            this.Hide( );
        }

        protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) {
            base.OnPropertyChanged( e );

            if( e.Property == VisibilityProperty && object.Equals( e.NewValue, Visibility.Visible ) ) {
                if( !string.IsNullOrEmpty( this.SelectedText ) )
                    this.search_.Text = this.SelectedText;
                this.search_.Focus( );
                this.search_.SelectAll( );
            }
        }


        private void UpdateSearchData( string find, string replace, bool searchNext, bool all ) {
            SearchData = new SearchData( find, replace, searchNext, this.IsCaseSensitive, this.UseRegex, this.Wrap, all );
        }

    }

}
